package ducpham.rogueconsole.mark2;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;

import javax.swing.JComponent;

/**
 * Class implementing a JComponent, Which display a dynamic character console.
 * The console would be useful for creating games based on ASCII graphics The
 * name is derived from roguelike games.
 * 
 * @author minhduc
 * 
 * @version: 0.01
 * @since: Apr 25t 2011
 * 
 * 
 */

public class RConsole extends JComponent{

	// generated serial id
	private static final long serialVersionUID = 8654226442439275259L;

	private static final Font FONT = new Font(Font.MONOSPACED, Font.BOLD, 14);

	private IRenderable[][] tiles;
	private Image buffer;
	private int width, height, rows, cols;

	private CharacterSpriteCanvas csc;

	/**
	 * @param initiate columns and rows the console have.
	 */
	public RConsole(int cols, int rows) {
		//setup csc and related params
		csc = new CharacterSpriteCanvas(FONT);
		width = cols * csc.getTileWidth();
		height = rows * csc.getTileHeight();
		this.rows = rows;
		this.cols = cols;
		//initial setting tiles and default data
		initData();
		//set preferred size and double buffering
		setFocusable(true);
		setDoubleBuffered(true);
		setPreferredSize(new Dimension(width, height));
	}
	
	public void initData(){
		tiles = new IRenderable[cols][rows];
		for (int x = 0; x < cols; x++) {
			for (int y = 0; y < rows; y++) {
				tiles[x][y] = csc.getNewTile(x, y);
				setChar(x, y, ".");
			}
		}
	}

	@Override
	public void paint(Graphics g) {
		paintBuffer();
		g.drawImage(buffer, 0, 0, this);
	}

	private void paintBuffer() {
		if (buffer == null) {
			buffer = new BufferedImage(width, height,
					BufferedImage.TYPE_4BYTE_ABGR);
		}
		Graphics2D g = (Graphics2D) buffer.getGraphics();
		g.setBackground(new Color(0x002b36));
		for (int x = 0; x < cols; x++) {
			for (int y = 0; y < rows; y++) {
				if (tiles[x][y].isChanged())
					tiles[x][y].render(g);
			}
		}
		g.dispose();
	}

	public void setChar(int x, int y, String ch) {
		if (x >= cols || y >= rows || x < 0 || y < 0)
			return;
		tiles[x][y].change(ATile.PARAM_CHAR, ch);
	}

	public void setColor(int x, int y, Color c) {
		if (x >= cols || y >= rows || x < 0 || y < 0)
			return;
		tiles[x][y].change(ATile.PARAM_COLOR, c);
	}
	
	public int getRows() {
		return rows;
	}
	
	public int getCols() {
		return cols;
	}
}